<?php
/**
 * Each engineer has a duty to keep the code elegant
 * Created by wolffy.
 * Author @wolffy<13750088090@sina.cn>
 * Date: 2018/9/2
 * Time: 15:13
 */
namespace App\Services;

use App\Repositories\PersonalAccountWithdrawRepository;
use App\Repositories\ThreeApiErrorLogsRepository;
use App\Repositories\UserBankCardRepository;
use App\Repositories\UserRepository;
use App\Services\RepaymentPay\RepaymentPayService;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;

class PersonalAccountWithdrawService extends CommonService
{
    protected $repaymentPayService;
    protected $userRepository;
    protected $userBankCardRepository;
    protected $personalAccountWithdrawRepository;
    protected $threeApiErrorLogsRepository;
    protected $messageService;

    public function __construct(RepaymentPayService $repaymentPayService,
                                UserRepository $userRepository,
                                UserBankCardRepository $userBankCardRepository,
                                PersonalAccountWithdrawRepository $personalAccountWithdrawRepository,
                                ThreeApiErrorLogsRepository $threeApiErrorLogsRepository,
                                MessageService $messageService)
    {
        $this->repaymentPayService = $repaymentPayService;
        $this->userRepository = $userRepository;
        $this->userBankCardRepository = $userBankCardRepository;
        $this->personalAccountWithdrawRepository = $personalAccountWithdrawRepository;
        $this->threeApiErrorLogsRepository = $threeApiErrorLogsRepository;
        $this->messageService = $messageService;
    }

    /**
     * 提现
     */
    public function withdraw($request, $userId, $realname)
    {
        if ($request->withdraw_money < 12) {
            return $this->responseJson(10700);//单笔提现最低金额12元
        }
        $userBankCardRepository = $this->userBankCardRepository->validateBankCardIsUser($request->bank_id, $userId);
        if (empty($userBankCardRepository)) {
            return $this->responseJson(10307);//储蓄卡不存在
        }
        //支付密码验证
        $user = $this->userRepository->byId($userId);
        $isCheck = $this->checkOldPassword($request->pay_password, $user->paypwd);
        if (!$isCheck) {
            return $this->responseJson(10112);//支付密码不正确
        }
        //提现
        $serviceCharge = 2;
        $withdrawMoney = $request->withdraw_money - $serviceCharge;
        $userProfit = $this->userRepository->byId($userId);
        $accountBalance = $userProfit->account_balance - $request->withdraw_money;
        //余额是否充足
        if ($accountBalance < 0) {
            return $this->responseJson(10702);//余额不足
        }
        $lockKey = $this->personalAccountWithdrawRedisKey() . $userId . '_LOCK';
        $isLock = $this->redis()->setnx($lockKey, 1); //加锁
        //获取锁权限
        if ($isLock) {
            $userProfit->update(['account_balance' => $accountBalance]);
            //释放锁
            $this->redis()->del($lockKey);
        } else {
            //防止死锁
            if($this->redis()->ttl($lockKey) == -1) {
                $this->redis()->expire($lockKey, 3);
            }
        }
        $orderNo = makeOrderNo();
        $result = $this->repaymentPayService->trade($orderNo, $realname, $userBankCardRepository->bank_no, $withdrawMoney);
        $errorData = [
            'order_no' => $orderNo,
            'error_code' => $result['response']['code'],
            'error_msg' => json_encode($result),
            'api_type' => 11
        ];
        $this->threeApiErrorLogsRepository->create($errorData);
        $data = [
            'withdraw_no' => $orderNo,
            'user_id' => $userId,
            'bank_card_id' => $userBankCardRepository->id,
            'bank_no' => $userBankCardRepository->bank_no,
            'bank_code' => $userBankCardRepository->bank_code,
            'bank_description' => $userBankCardRepository->bank_description,
            'withdraw_money' => $request->withdraw_money,
            'withdraw_service_charge' => $serviceCharge,
            'create_time' => time(),
        ];
        if ($result['response']['code'] == 0) {
            $data['withdraw_status'] = 5001;
            $this->personalAccountWithdrawRepository->create($data);
            return $this->responseJson(0);
        } else {
            $data['withdraw_status'] = 5003;
            $data['fail_message'] = $result['response']['message'];
            $this->personalAccountWithdrawRepository->create($data);
            return $this->responseJson(10701, [], false, $result['response']['message'], $result['response']['message']);
        }
    }

    /**
     * 交易明细
     * @param $userId
     * @param $status
     * @return \Illuminate\Http\JsonResponse
     */
    public function tradeDetail($userId, $status, $page)
    {
        if (0 === $status) {
            $data = $this->personalAccountWithdrawRepository->getTradeRecordAll($userId, $page, 30);
        } else {
            $data = $this->personalAccountWithdrawRepository->getTradeRecordToStatus($userId, $status, $page, 30);
        }
        return $this->responseJson(0, $data);
    }

    /**
     * 交易查询是否到账任务
     * 00 成功 02 失败 04订单关闭 01 处理中 半个小时后再次发起对账。 99 订单号不存在
     * array:7 [
     * "transcode" => "902"
     * "merchno" => "lmkj25se267f69f"
     * "dsorderid" => "A904652975751551"
     * "sign" => "5ebf820a840cb272fedd1170672015a1"
     * "returncode" => "0000"
     * "errtext" => "成功"
     * "status" => "99"
     * ]
     * array:14 [
     * "transcode" => "902"
     * "merchno" => "lmkj25se267f69f"
     * "dsorderid" => "A904456629703671"
     * "sign" => "6bc4fa26053917187f393cb6d8eaeaf9"
     * "returncode" => "0000"
     * "errtext" => "成功"
     * "orderid" => "2018090415173500100120279"
     * "amount" => "10.00"
     * "status" => "00"
     * "transtype" => "20"
     * "currency" => "CNY"
     * "paytime" => "20180904153636"
     * "signType" => "MD5"
     * "message" => "成功"
     * ]
     */
    public function tradeQueryJobs()
    {
        Log::alert('tradeQueryJobs');
        $personalAccountWithdrawQueryRedisKey = $this->personalAccountWithdrawQueryRedisKey();
        $getTrade = $this->redis()->lRange($personalAccountWithdrawQueryRedisKey, 0, -1);
        if (!empty($getTrade)) {
            foreach ($getTrade as $key=>$value) {
                //第三方接口单次访问需2s，防止并发，1分钟对账10条
                if ($key < 10) {
                    $info = json_decode($value, true);
                    $result = $this->landingRepaymentCService->receiveAndPaymentSelect($info['withdraw_no'], 'tradeQuery');
                    //成功
                    if ($result['status'] == '00') {
                        $this->personalAccountWithdrawRepository->updateStatusByWithdrawNo($result['dsorderid'], 5002);//成功
                        $this->redis()->lRem($personalAccountWithdrawQueryRedisKey, 0, $value);
                        //发送账户余额提现成功消息提醒
                        $field = $this->personalAccountWithdrawRepository->byWithdrawNo($result['dsorderid']);
                        $user = $this->userRepository->byId($info['user_id']);
                        $this->messageService->messageTemplate(13, $user->invited_code, $info['bank_no'], $info['bank_description'],
                            $info['withdraw_money'], '', '', $field->id, '', '');
                    }
                    //失败或订单号不存在
                    if ($result['status'] == '02' || $result['status'] == '04' || $result['status'] == '99') {
                        $this->personalAccountWithdrawRepository->updateStatusByWithdrawNo($result['dsorderid'], 5003);//失败
                        $this->redis()->lRem($personalAccountWithdrawQueryRedisKey, 0, $value);
                        //账户余额加
                        $field = $this->personalAccountWithdrawRepository->byWithdrawNo($result['dsorderid']);
                        if (!empty($field)) {
                            $userProfit = $this->userRepository->byId($field->user_id);
                            $accountBalance = $userProfit->account_balance + $field->withdraw_money;
                            $userProfit->update(['account_balance' => $accountBalance]);
                        }
                        //发送账户余额提现失败消息提醒
                        $user = $this->userRepository->byId($info['user_id']);
                        $this->messageService->messageTemplate(14, $user->invited_code, $info['bank_no'], $info['bank_description'],
                            $info['withdraw_money'], '', '', $field->id, '', '');
                    }
                }
            }
        }
    }

    /**
     * 检查旧密码是否正确
     * @param $inputPassword
     * @param $hashedPassword
     * @return bool
     */
    protected function checkOldPassword($inputPassword, $hashedPassword)
    {
        if (Hash::check($inputPassword, $hashedPassword)) {
            return true;
        }
        return false;
    }


}